#!/usr/bin/env python
# -*- coding: utf-8 -*-
from selenium import webdriver
import time, os
from common import BASEDIR, L, toDict
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.touch_actions import TouchActions
from types import FunctionType, MethodType
import importlib

__author__ = 'Administrator'


class MyDriver():
    def __init__(self, driver: webdriver):
        """
        :param driver: webdriver实例,例如(chrome,firefox,ie)
        """
        self.driver = driver
        self.driver.maximize_window()

    def sleep(self, s: int):
        time.sleep(s)

    def get(self, url, time_wait=3):
        self.driver.get(url)
        if isinstance(time_wait, int):
            self.sleep(time_wait)

    def forward(self):
        self.driver.forward()

    def back(self):
        self.driver.back()

    def quit(self):
        self.driver.quit()

    def refresh(self):
        self.driver.refresh()

    def excute_script(self, js):
        self.driver.excute_script(js)

    def implicitly_wait(self, s):
        self.driver.implicitly_wait(s)

    def get_screenshot_as_base64(self):
        return self.driver.get_screenshot_as_base64()

    def screen_shot(self, pic_name=None):
        if pic_name:
            rq = pic_name
        else:
            rq = time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time())) + '.png'
        screen_name = os.path.join(BASEDIR, rq)
        try:
            self.driver.get_screenshot_as_file(screen_name)
        except NameError as e:
            L.warning(e)
            self.screen_shot(pic_name)

    def __getattr__(self, item) -> webdriver:
        """To support other attrs belongs to webdriver, but doesn't overwrite in MyDriver"""
        try:
            _item = getattr(self.driver, item)
            if isinstance(_item, (FunctionType, MethodType)) or callable(_item):
                def __(*args, **kw):
                    return _item(*args, **kw)

                return __
            else:
                return _item
        except AttributeError as e:
            raise AttributeError(e)

    def web_driver_wait(self, max_time, min_time, locator):
        element = self._find_element(locator, is_need_displayed=False)
        WebDriverWait(self.driver, max_time, min_time).until(EC.presence_of_element_located(element))

    def _send_keys(self, locator, text, clear_first=False, click_first=True):
        __ = self._find_element(locator)
        if click_first:
            __.click()
        if clear_first:
            __.clear()
        __.send_keys(text)

    def _click(self, locator, count=1):
        __ = self._find_element(locator)
        if count == 1:
            __.click()
        else:
            touchAction = TouchActions(self.driver)
            try:
                for x in range(count):
                    touchAction.tap(__).perform()
            except Exception as e:
                L.info(e)

    def _text(self, locator):
        return self._find_element(locator).text

    def _get_attribute(self, locator, value2):
        Value = self._find_element(locator).get_attribute(value2)
        return Value

    def _is_selected(self, locator):
        return self._find_element(locator).is_selected()

    def _find_element(self, locator, is_need_displayed=True):
        if 'time_out' in locator:
            wait = locator['time_out']
        else:
            wait = 20
        try:
            if is_need_displayed:
                WebDriverWait(self.driver, wait).until(lambda driver: self.get_element(locator).is_displayed())
            else:
                WebDriverWait(self.driver, wait).until(lambda driver: self.get_element(locator) is not None)
            return self.get_element(locator)
        except Exception as e:
            L.error("[element] can not find {} cause {}".format(locator, e))
            raise e

    def _find_elements(self, locator):
        if 'time_out' in locator:
            wait = locator['time_out']
        else:
            wait = 20
        try:
            WebDriverWait(self.driver,
                          wait).until(lambda driver: self.get_element(locator, False).__len__() > 0)
            return self.get_element(locator, False)
        except Exception as e:
            L.error("[element] can not find {} cause {}".format(locator, e))
            raise e

    def get_element(self, locator, element=True):
        value = locator['value']
        ltype = locator['type']
        __switch_case = {
            'id': By.ID,
            'xpath': By.XPATH,
            'name': By.NAME,
            'link_text': By.LINK_TEXT,
            'partial': By.PARTIAL_LINK_TEXT,
            'tag': By.TAG_NAME,
            'class': By.CLASS_NAME,
            'css': By.CSS_SELECTOR
        }
        try:
            ltype = __switch_case[ltype]
            L.info("find_ele {}".format(locator))
            return self.driver.find_element(ltype, value) if element else self.driver.find_elements(ltype, value)
        except KeyError as e:
            L.error('type {} not support'.format(e))
            raise e

    @property
    def hotPlug(self):
        importedModule = importlib.import_module('hotPlug')
        module_functions = {}
        for name, item in vars(importedModule).items():
            if isinstance(item, FunctionType):
                module_functions[name] = item
        return toDict(module_functions)

if __name__ == '__main__':
    pass
